﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TrackerRealm.Jazz.Client;
using TrackerRealm.Jazz.Common;
using TrackerRealm.Jazz.Client.Custom;

namespace ConsoleDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WindowWidth = 140;
            #region Introduction Dialog
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Executing from Visual Studio?");
            Console.WriteLine("Visual Studio may not allow this program to catch exceptions as required.  ");
            Console.WriteLine("This results is a pop up box stating 'Unhandled Exception'");
            Console.WriteLine("To resolve:Uncheck 'Tools/Options/Debugging/General -- 'Enable Just my Code'.");
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("Okay?....hit any key to continue");
            Console.ReadKey();
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine();
            Console.WriteLine("This application uses Color coding.");
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Red is used for 'Greyed Out' commands or 'Exceptions'.");
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Green is used for valid commands.");
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("Yellow is for important imformation.");
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine("Okay?....hit any key to continue");
            Console.ReadKey();
            Console.WriteLine();
            #endregion
            #region Verbose Question
            Console.Write("Verbose? y/n :>");
            ConsoleKeyInfo key = Console.ReadKey();
            VerboseType verboseSetting = VerboseType.Off;
            if (key.KeyChar.ToString().ToLower() == "y")
            {
                verboseSetting = VerboseType.All;
            }
            if (key.KeyChar != '\n')
                Console.WriteLine();
            Console.WriteLine(string.Format("Verbose Setting = '{0}'", verboseSetting));
            Console.WriteLine();
            #endregion
            Console.ForegroundColor = ConsoleColor.Gray;
            // configure the Jazz Nexus
            NexusConfig config = new NexusConfig()
            {
                LoginProfile = jUser.Create("MyUser"),
                RoleCheckCollection = new string[]{"Manager"},
                Verbose = verboseSetting,
            };
            // start the Jazz Nexus
            using (ClientNexus nexus = ClientNexus.Create(config))
            {
                //create a jazz object 
                PersonnelRequest request = new PersonnelRequest(nexus);
                // create a second user
                jUser boss = jUser.Create(nexus, "Boss", "Manager");
                
                while (true) 
                {
                    JazzConsole.DispalyJazzObject(request);
                    jUser loginUser;
                    if(!JazzConsole.GetLoginUser(nexus, out loginUser)) 
                        break;
                    nexus.ChangeLoginProfile(loginUser);

                }
                #region End of Program Dialog
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine();
                Console.WriteLine("*** End of program ***");
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("hit any key to close");
                Console.ReadKey();
                #endregion
            }
        }
        #region PersonnelRequest Class 
        /// <summary>
        /// This is a small class that demonstrates the use of states 
        /// and roles in a personel request.
        /// The class is very simple only allowing a request to made and
        /// then approved.
        /// </summary>
        [Jazz]
        public class PersonnelRequest : jObject
        {
            #region Constructor
            /// <summary>
            /// Constructor - auto binds
            /// </summary>
            public PersonnelRequest(ClientNexus nexus)
                : base(nexus)
            {
                this.requestData = "";
                this.IsApproved = false;
                if(this.IsEmpty)
                    Owner = (jProfile)nexus.LoginProfile.Class.EmptyInstance;
                else
                    this.Owner = nexus.LoginProfile;
            }
            #endregion
            #region Owner
            /// <summary>
            /// Returns the user that created this 'PersonnelRequest' instance.
            /// </summary>
            public jProfile Owner { get; private set; }
            #endregion
            #region Request
            private string requestData;
            /// <summary>
            /// Make a request by setting the data.
            /// Only the Jazz Object owner
            /// is allowed to set the data.
            /// </summary>
            [UI]
            public string Request
            {
                get { return this.requestData; }
                [GrantStates("Start")]
                [GrantProperty("Owner")]  // only allow the owner to make changes.
                set
                {
                    this.requestData = value;
                    // prevent the data from being changed.
                    this.EnterState("Approval");
                }
            }
            #endregion
            #region IsApproved
            /// <summary>
            /// Returns true when the Request has been approved.
            /// </summary>
            [UI]
            public bool IsApproved
            {
                get;
                private set;
            }
            #endregion
            #region Approve/Edit
            /// <summary>
            /// The approve method is only allowed to be executed when this instance is the 'Approval State'.
            /// </summary>
            [UI]
            [GrantStates("Approval")]
            [GrantRoles("Manager")]
            public void Approve()
            {
                this.IsApproved = true;
                // prevent the workflow from being approved again.
                this.EnterState("Completed");
            }
            /// <summary>
            /// Return to Start state to edit the request.  Only the Jazz Object owner
            /// is allowed to perform this action.
            /// </summary>
            [UI]
            [GrantStates("Approval")]
            [GrantProperty("Owner")]
            public void Edit()
            {
                this.EnterState("Start");
            }
            #endregion
            #region States
            //
            // A ProfilelRequest instance has its 'CurrentState' set to one
            // of the following states.
            //
            #region Start
            [StartState]
            void Start()
            {
            }
            #endregion
            #region Completed
            [FinalState]
            void Completed()
            {
                // this will be written to the console when the state is entered.
                Console.WriteLine(this.ToString() + "\t\t***** Completed ******");
            }
            #endregion
            #region Approval
            [FinalState]
            void Approval()
            {
            }
            #endregion
            #endregion
        }
        #endregion
    }
}
